﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz.Net.BLL;
using Quartz.Net.Model;
using Quartz.Net.Utils;
using System.Configuration;
using Quartz.Spi;

namespace Quartz.Net.Factory
{
    public class factoryClass
    {
        static Task_Quartz_JobtriggerBLL JobtriggerBLL = new Task_Quartz_JobtriggerBLL();
        static Task_Quartz_OneJobRunLogBLL oneBll = new Task_Quartz_OneJobRunLogBLL();
        static Task_Quartz_RunBLL runBll = new Task_Quartz_RunBLL();
        static Task_Quartz_OldrunBLL OldrunBLL = new Task_Quartz_OldrunBLL();
        static Task_Quartz_JoinBLL JoinBLL = new Task_Quartz_JoinBLL();
        static Task_Quartz_OperationLogBLL operBLL = new Task_Quartz_OperationLogBLL();

        /// <summary>
        /// 操作日志
        /// </summary>
        /// <param name="JOBGUID">jobID</param>
        /// <param name="status">操作类型 1：启动 2：暂停 3：新增 4：删除 5：修改 6：查询</param>
        /// <param name="OPERATETOR">操作人编号</param>
        /// <param name="OPERATETORNAME">操作人姓名</param>
        /// <param name="OPERATEIP">操作人ip</param>
        /// <param name="OPERATEDETAILS">操作详情</param>
        /// <returns></returns>
        public static int InsertOperation(string JOBGUID, OperateStatus status, string OPERATETOR, string OPERATETORNAME, string OPERATEIP, string OPERATEDETAILS)
        {
            Task_Quartz_OperationLogModel model = new Task_Quartz_OperationLogModel();
            model.JOBGUID = JOBGUID;
            model.OPERATESTATUS = ((int)status).ToString();
            model.OPERATETOR = OPERATETOR;
            model.OPERATETORNAME = OPERATETORNAME;
            model.OPERATEIP = OPERATEIP;
            model.OPERATEDETAILS = OPERATEDETAILS;

            model.NGUID = Guid.NewGuid().ToString();
            model.OPERATETIME = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            model.OPERATEDATE = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
            model.VALID = "1";
            //return 1;
            return operBLL.InsertOperation(model);
        }

        public static int MaxXh()
        {
            return JobtriggerBLL.MaxXh();
           
        }
        public static int InsertJob(Task_Quartz_JobTriggerModel model)
        {
            model.NGUID = Guid.NewGuid().ToString();
            int xh = JobtriggerBLL.MaxXh();
            model.JOBNAME = "job"+xh;
            model.JOBGROUPNAME = "group" + xh;
            model.TRIGGERNAME = "trigger" + xh;
            model.TRIGGERGROUPNAME = "group" + xh;
            model.JOBPATH = ConfigurationManager.AppSettings["TaskPath"].ToString() + model.JOBNAME+@"\";
            model.XH = xh.ToString();
            model.VALID = "1";
            model.RUNSTATUS = "3";
            model.ISCHANGE = "0";


           return JobtriggerBLL.InsertJob(model);
        }

        public static IEnumerable<Task_Quartz_JobtriggerRunModel> GetJobRun()
        {
            return JoinBLL.GetJobRun();
        }

        /// <summary>
        /// 获取任务表信息
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Task_Quartz_JobTriggerModel> JobTriggerGetInfo()
        {

            IEnumerable<Task_Quartz_JobTriggerModel> IeJob = null;
            try
            {
                return JobtriggerBLL.GetInfo();
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "获取任务表信息失败", LogsStatus.Fatal);
                return IeJob;
            }

        }

        /// <summary>
        /// 获取任务表信息
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Task_Quartz_RunModel> RunGetInfo()
        {

            IEnumerable<Task_Quartz_RunModel> IeJob = null;
            try
            {
                return runBll.GetInfo();
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "获取任务表信息失败", LogsStatus.Fatal);
                return IeJob;
            }

        }
        /// <summary>
        /// 更新是否变更
        /// </summary>
        /// <param name="guid"></param>
        /// <param name="change"></param>
        public static void UpdateISChange(string guid, string change)
        {
            try
            {
                JobtriggerBLL.UpdateISChange(guid, change);
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "更新是否变更失败", LogsStatus.Fatal);
            }

        }

        /// <summary>
        /// 任务添加
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobAdd(string JobName, List<DateTime> listDate)
        {
            try
            {
                //筛选信息
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    Task_Quartz_RunModel runModel = new Task_Quartz_RunModel();
                    runModel.NGUID = Guid.NewGuid().ToString();
                    runModel.JOBGUID = list[0].NGUID;
                    runModel.LASTTIME = DateTime.Now;
                    runModel.NEXTTIME = listDate[0];
                    runModel.VALID = "1";
                    runBll.InsertRun(runModel);
                    InsertOneJobRun(runModel.NGUID, list[0].NGUID, JobName + ":Job添加进调度程序");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "任务添加失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// 任务删除
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobDeleted(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    JobtriggerBLL.UpdateValid(list[0].NGUID, "0");
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();
                    runBll.DeleteRun(list[0].NGUID);
                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job从调度程序中删除");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "任务删除失败", LogsStatus.Fatal);
            }

        }

        /// <summary>
        /// 暂停任务删除
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobDeletedZt(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    //JobtriggerBLL.UpdateValid(list[0].NGUID, "0");
                    
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();
                    runBll.DeleteRun(list[0].NGUID);
                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job从调度程序中暂停");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "任务删除失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// 任务暂停
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobPaused(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    JobtriggerBLL.UpdateRunStatus(list[0].NGUID, RunStatus.Suspend);
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();
                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job从调度程序中暂停");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "任务暂停失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// 任务从暂停变重启
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobResumed(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    JobtriggerBLL.UpdateRunStatus(list[0].NGUID, RunStatus.Wait);
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();
                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job从调度程序中恢复运行");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "任务从暂停变重启失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// Job执行时调用
        /// </summary>
        /// <param name="JobName"></param>
        public static void TriggerFired(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();
                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job执行前调用");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "Job执行时调用失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// Job完成时调用
        /// </summary>
        /// <param name="JobName"></param>
        public static void TriggerComplete(string JobName, DateTime NEXTTIME)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();

                    Task_Quartz_OldRunModel oldRunModel = new Task_Quartz_OldRunModel();
                    oldRunModel.NGUID = listRun[0].NGUID;
                    oldRunModel.JOBGUID = list[0].NGUID;
                    oldRunModel.LASTTIME = listRun[0].LASTTIME;
                    oldRunModel.NEXTTIME = listRun[0].NEXTTIME;
                    oldRunModel.JOBRUNTIME = (DateTime.Now.Subtract(listRun[0].NEXTTIME).Hours*60*60 + DateTime.Now.Subtract(listRun[0].NEXTTIME).Minutes*60 + DateTime.Now.Subtract(listRun[0].NEXTTIME).Seconds).ToString();
                    oldRunModel.INSERTTIME = DateTime.Now;
                    oldRunModel.INSERTDATE = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
                    oldRunModel.VALID = "1";
                    OldrunBLL.InsertOldRun(oldRunModel);
                    runBll.DeleteRun(list[0].NGUID);

                    Task_Quartz_RunModel runModel = new Task_Quartz_RunModel();
                    runModel.NGUID = Guid.NewGuid().ToString();
                    runModel.JOBGUID = list[0].NGUID;
                    runModel.LASTTIME = listRun[0].NEXTTIME;
                    runModel.NEXTTIME = NEXTTIME;
                    runModel.VALID = "1";
                    runBll.InsertRun(runModel);

                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job完成后调用");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "Job完成时调用失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// Job即将执行
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobToBeExecuted(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();
                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job即将执行");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "Job即将执行失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// Job刚执行完成
        /// </summary>
        /// <param name="JobName"></param>
        public static void JobWasExecuted(string JobName)
        {
            try
            {
                List<Task_Quartz_JobTriggerModel> list = new List<Task_Quartz_JobTriggerModel>(JobTriggerGetInfo().Where(m => m.VALID == "1" && m.JOBNAME == JobName));
                if (list.Count > 0)
                {
                    List<Task_Quartz_RunModel> listRun = runBll.GetOntInfo(list[0].NGUID).ToList();

                    InsertOneJobRun(listRun[0].NGUID, list[0].NGUID, JobName + ":Job刚执行完成");
                }
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "Job刚执行完成失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// 往单个任务运行记录表插入数据
        /// </summary>
        /// <param name="runNguid">运行id</param>
        /// <param name="JobGuid">任务id</param>
        /// <param name="Operatedetails">操作信息</param>
        public static void InsertOneJobRun(string runNguid, string JobGuid, string Operatedetails)
        {
            try
            {
                Task_Quartz_OneJobRunLogModel oneJobModel = new Task_Quartz_OneJobRunLogModel();
                oneJobModel.NGUID = Guid.NewGuid().ToString();
                oneJobModel.RUNGUID = runNguid;
                oneJobModel.JOBGUID = JobGuid;
                oneJobModel.OPERATEDETAILS = Operatedetails;
                oneJobModel.OPERATETIME = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                oneJobModel.OPERATEDATE = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
                oneJobModel.VALID = "1";
                oneBll.InsertOneJobRun(oneJobModel);
            }
            catch (Exception ex)
            {
                InsertRrrorlog(ex.Message, "往单个任务运行记录表插入数据失败", LogsStatus.Fatal);
            }

        }
        /// <summary>
        /// 错误信息插入
        /// </summary>
        /// <param name="ERRORLOG">错误信息</param>
        public static void InsertRrrorlog(string ERRORLOG, string LOGACTIONCLICK, LogsStatus logsStatus)
        {

            try
            {
                switch (logsStatus)
                {
                    case LogsStatus.Fatal:
                        Logs.Fatal(ERRORLOG, LOGACTIONCLICK);
                        break;
                    case LogsStatus.Error:
                        Logs.Error(ERRORLOG, LOGACTIONCLICK);
                        break;
                    case LogsStatus.Warn:
                        Logs.Warn(ERRORLOG, LOGACTIONCLICK);
                        break;
                    case LogsStatus.Info:
                        Logs.Info(ERRORLOG, LOGACTIONCLICK);
                        break;
                    case LogsStatus.Debug:
                        Logs.Debug(ERRORLOG, LOGACTIONCLICK);
                        break;
                    default:
                        throw new Exception("未找到错误信息枚举");
                }
            }
            catch (Exception)
            {

                //throw;
            }


        }

        /// <summary>
        /// 删除所有正在运行的记录
        /// </summary>
        public static void DeleteRunAll()
        {
            runBll.DeleteRun();
        }

        public static void UpdateJobInfo(Task_Quartz_JobTriggerModel model)
        {
            JobtriggerBLL.UpdateJob(model);
        }
        public static void UpdateJobValid(Task_Quartz_JobTriggerModel model)
        {
            JobtriggerBLL.UpdateValid(model.NGUID,model.VALID);
        }

        public static void UpdateRunStatus(string NGUID, RunStatus status)
        {
            JobtriggerBLL.UpdateRunStatus(NGUID, status);
        }

        public static bool ValidExpression(string cron)
        {
            return CronExpression.IsValidExpression(cron);
        }

        /// <summary>
        /// 获取任务在未来周期内哪些时间会运行
        /// </summary>
        /// <param name="CronExpressionString">Cron表达式</param>
        /// <param name="numTimes">运行次数</param>
        /// <returns>运行时间段</returns>
        public static List<string> GetNextFireTime(string CronExpressionString, int numTimes)
        {
            if (numTimes < 0)
            {
                throw new Exception("参数numTimes值大于等于0");
            }
            //时间表达式
            ITrigger trigger = TriggerBuilder.Create().WithCronSchedule(CronExpressionString).Build();
            IList<DateTimeOffset> dates = TriggerUtils.ComputeFireTimes(trigger as IOperableTrigger, null, numTimes);
            List<string> list = new List<string>();
            foreach (DateTimeOffset dtf in dates)
            {
                //list.Add(TimeZoneInfo.ConvertTimeFromUtc(dtf.DateTime, TimeZoneInfo.Local));
                list.Add(TimeZoneInfo.ConvertTimeFromUtc(dtf.DateTime, TimeZoneInfo.Local).ToString());
            }
            return list;
        }
    }
}
